home *** CD-ROM | disk | FTP | other *** search
- /*
- File: GXEditScrap.c
-
- Contains:
-
- Written by: Barton R. House
-
- Copyright: © 1993 by Apple Computer, Inc., All rights reserved.
-
- */
-
- #include <Scrap.h>
- #include <Script.h>
- #include <Errors.h>
- #include <Fonts.h>
-
- #include "PrintingManager.h"
- #include "graphics routines.h"
- #include "graphics libraries.h"
- #include "font routines.h"
- #include "math routines.h"
- #include "layout routines.h"
- #include "font menu library.h"
-
- #include "GXEdit.h"
- #include "GXEditDebug.h"
- #include "GXEditDoc.h"
- #include "GXEditScrap.h"
- #include "GXEditError.h"
- #include "GXEditNewRun.h"
- #include "GXEditStyle.h"
-
- #define kGXEditScrapType 'gxdt'
- #define kGXEditScrapMagic 0x3abf435d
- #define kGXEditScrapVersion 0x0
-
- #define kTextScrapType 'TEXT'
- #define kStyleScrapType 'styl'
-
- #define kBufferSize 2048
- #define kChunkSize 1024
-
- typedef struct {
- gxSpoolBlock sb; /* this must be first */
- Handle buf;
- long * pos;
- long numBytes;
- long start;
- DocPtr dp;
- } MySpoolBlock;
-
- static long MySpoolProcedure(gxSpoolCommand command, gxSpoolBlock * sb);
-
- static Handle ScrapToHandle(DocPtr dp);
- static void HandleToScrap(DocPtr dp, Handle scrap);
-
- static void ScrapToText(DocPtr dp, Handle * text, long * textSize, Handle * gxStyle, long * styleSize);
- static void TextToScrap(DocPtr dp, Handle text, Handle gxStyle);
-
- static void WriteLong(Handle scrap, long *pos, long value);
- static void WriteNewRun(Handle scrap, long *pos, NewRunPtr rp);
- static void WriteStyle(DocPtr dp, Handle scrap, long *pos, short styleIndex);
- static void WriteData(Handle scrap, long * pos, void * buf, long size);
-
- static void ReadLong(Handle scrap, long *pos, long *value);
- static void ReadNewRun(Handle scrap, long *pos, NewRunPtr rp);
- static void ReadStyle(DocPtr dp, Handle scrap, long *pos, short *styleIndex);
- static void ReadData(Handle scrap, long * pos, void * buf, long size);
-
- static void SetStyle(DocPtr dp, short styleIndex, ScrpSTElement * sp, long start);
- static short GetStyle(DocPtr dp, ScrpSTElement * sp);
-
- void gxEditScrapToDesk(DocPtr dp)
- {
- Handle scrap, text, gxStyle;
- long textSize, styleSize;
-
- ZeroScrap();
-
- /* GX Scrap Information */
-
- scrap = ScrapToHandle(dp);
-
- HLock((Handle) scrap);
-
- PutScrap(GetHandleSize(scrap), kGXEditScrapType, *scrap);
-
- HUnlock((Handle) scrap);
-
- DisposeHandle(scrap);
-
- /* Text Information -- Text Edit text and style */
-
- ScrapToText(dp, &text, &textSize, &gxStyle, &styleSize);
-
- HLock((Handle) text);
- HLock((Handle) gxStyle);
-
- PutScrap(textSize, kTextScrapType, *text);
- PutScrap(styleSize, kStyleScrapType, *gxStyle);
-
- HUnlock((Handle) text);
- HUnlock((Handle) gxStyle);
-
- DisposeHandle((Handle) text);
- DisposeHandle((Handle) gxStyle);
-
- }
-
- void gxEditScrapFromDesk(DocPtr dp)
- {
- Handle scrap, text, gxStyle;
- long offset;
- long length;
-
- if(GetScrap(nil, kGXEditScrapType, &offset) > 0) {
-
- scrap = NewHandle(0);
-
- if(GXEditDebug)
- RemoveBlock((long) scrap);
-
- length = GetScrap(scrap, kGXEditScrapType, &offset);
-
- if(GXEditDebug)
- AddBlock((long) scrap, length, true);
-
- HandleToScrap(dp, scrap);
-
- DisposeHandle(scrap);
-
- } else if(GetScrap(nil, kTextScrapType, &offset) > 0) {
-
- text = NewHandle(0);
-
- if(GXEditDebug)
- RemoveBlock((long) text);
-
- length = GetScrap(text, kTextScrapType, &offset);
-
- if(GXEditDebug)
- AddBlock((long) text, length, true);
-
- if(GetScrap(nil, kStyleScrapType, &offset) > 0) {
-
- gxStyle = NewHandle(0);
-
- if(GXEditDebug)
- RemoveBlock((long) text);
-
- length = GetScrap(gxStyle, kStyleScrapType, &offset);
-
- if(GXEditDebug)
- AddBlock((long) gxStyle, length, true);
-
- } else
- gxStyle = nil;
-
- TextToScrap(dp, text, gxStyle);
-
- DisposeHandle(text);
- if(gxStyle != nil)
- DisposeHandle(gxStyle);
-
- } else {
-
- gxEditEmptyScrap(dp);
-
- }
-
-
- }
-
- static Handle ScrapToHandle(DocPtr dp)
- {
- long pos;
- long numRuns;
- NewRunPtr rp;
- short i;
- Handle scrap;
-
- pos = 0;
- scrap = NewHandle(0);
-
- numRuns = dp->scrap.numRuns;
-
- WriteLong(scrap, &pos, kGXEditScrapMagic);
- WriteLong(scrap, &pos, kGXEditScrapVersion);
- WriteLong(scrap, &pos, numRuns);
-
- HLock((Handle) dp->scrap.runs);
-
- rp = * dp->scrap.runs;
- for(i=0; i<numRuns; i++, rp++) {
-
- WriteNewRun(scrap, &pos, rp);
- WriteStyle(dp, scrap, &pos, rp->styleIndex);
-
- }
-
- HUnlock((Handle) dp->scrap.runs);
-
- return(scrap);
-
- }
-
- static void WriteLong(Handle scrap, long * pos, long value)
- {
- if(*pos + sizeof(long) > GetHandleSize(scrap) )
- SetHandleSize((Handle) scrap, *pos + sizeof(long));
-
- *((long *) (((Ptr) *scrap) + *pos)) = value;
-
- *pos += sizeof(long);
- }
-
- static void WriteData(Handle scrap, long * pos, void * buf, long size)
- {
- if(*pos + size > GetHandleSize(scrap) )
- SetHandleSize((Handle) scrap, *pos + size + kChunkSize);
-
- BlockMove((Ptr) buf, ((Ptr) *scrap) + *pos, size);
-
- *pos += size;
- }
-
- static void WriteNewRun(Handle scrap, long * pos, NewRunPtr rp)
- {
- long size;
-
- if(*pos + sizeof(NewRunRec) > GetHandleSize(scrap) )
- SetHandleSize((Handle) scrap, *pos + sizeof(NewRunRec));
-
- *((NewRunPtr) (((Ptr) *scrap) + *pos)) = *rp;
-
- *pos += sizeof(NewRunRec);
-
- /* write out the text information */
-
- HLock((Handle) rp->text);
-
- size = rp->numText;
- WriteData(scrap, pos, (void *) *rp->text, size);
-
- HUnlock((Handle) rp->text);
-
- }
-
- void gxEditDisposeScrap(DocPtr dp)
- {
- gxEditEmptyScrap(dp);
-
- DisposeHandle((Handle) dp->scrap.runs);
- dp->scrap.runs = nil;
-
- }
-
- void gxEditEmptyScrap(DocPtr dp)
- {
- NewRunPtr rp;
- short i;
-
- /* walk the runs that are in the scrap now, decrementing the style ref counts */
-
- HLock((Handle) dp->scrap.runs);
-
- rp = * dp->scrap.runs;
- for(i=0; i<dp->scrap.numRuns; i++, rp++)
- DisposeNewRun(dp, rp);
-
- HUnlock((Handle) dp->scrap.runs);
-
- SetHandleSize((Handle) dp->scrap.runs, 0);
-
- dp->scrap.numRuns = 0;
-
- }
-
- static void HandleToScrap(DocPtr dp, Handle scrap)
- {
- long pos;
- long magic;
- long version;
- long numRuns;
- NewRunPtr rp;
- short i;
-
- pos = 0;
-
- ReadLong(scrap, &pos, &magic);
- ReadLong(scrap, &pos, &version);
- ReadLong(scrap, &pos, &numRuns);
-
- if(magic != kGXEditScrapMagic || version != kGXEditScrapVersion)
- gxEditPostError(dp, gx_edit_internal_fatal_error);
-
- if(numRuns < 0)
- gxEditPostError(dp, gx_edit_internal_fatal_error);
-
- /* clean up old scrap */
-
- gxEditEmptyScrap(dp);
-
- /* setup the scrap runs in the document */
-
- dp->scrap.numRuns = numRuns;
- SetHandleSize((Handle) dp->scrap.runs, sizeof(NewRunRec) * numRuns);
- dp->scrap.numText = 0;
-
- HLock((Handle) dp->scrap.runs);
-
- rp = * dp->scrap.runs;
- for(i=0; i<numRuns; i++, rp++) {
-
- ReadNewRun(scrap, &pos, rp);
- ReadStyle(dp, scrap, &pos, &rp->styleIndex);
-
- IncrementDocStyleRefCount(dp, rp->styleIndex);
-
- dp->scrap.numText += rp->numText;
- }
-
- HUnlock((Handle) dp->scrap.runs);
-
- }
-
- static void ReadLong(Handle scrap, long * pos, long * value)
- {
- if(*pos + sizeof(long) > GetHandleSize(scrap) )
- gxEditPostError(nil, gx_edit_internal_fatal_error);
-
- *value = *((long *) (((Ptr) *scrap) + *pos));
-
- *pos += sizeof(long);
- }
-
- static void ReadData(Handle scrap, long * pos, void * buf, long size)
- {
- if(*pos + size > GetHandleSize(scrap) )
- gxEditPostError(nil, gx_edit_internal_fatal_error);
-
- BlockMove(((Ptr) *scrap) + *pos, (Ptr) buf, size);
-
- *pos += size;
- }
-
-
- static void ReadNewRun(Handle scrap, long * pos, NewRunPtr rp)
- {
- long size;
-
- if(*pos + sizeof(NewRunRec) > GetHandleSize(scrap) )
- gxEditPostError(nil, gx_edit_internal_fatal_error);
-
- *rp = *((NewRunPtr) (((Ptr) *scrap) + *pos));
-
- *pos += sizeof(NewRunRec);
-
- /* read in the text */
-
- size = rp->numText;
- rp->text = (void **) NewHandle(size);
-
- ReadData(scrap, pos, *rp->text, size);
-
- }
-
- static void ReadStyle(DocPtr dp, Handle scrap, long * pos, short * styleIndex)
- {
- MySpoolBlock msb;
- gxShape emptyShape;
- StyleRec gxStyle;
- long styleSize;
-
- /* read size of following data */
-
- ReadLong(scrap, pos, &styleSize);
-
- /* read in the GX gxStyle information */
-
- msb.sb.buffer = NewPtr(kBufferSize);
- msb.sb.bufferSize = kBufferSize;
- msb.sb.spoolProcedure = MySpoolProcedure;
-
- msb.numBytes = styleSize;
- msb.buf = scrap;
- msb.pos = pos;
- msb.start = *pos;
- msb.dp = dp;
-
- emptyShape = GXUnflattenShape((gxSpoolBlock *) &msb, 1, &dp->docViewPort );
-
- /* check that the correct number of bytes was read */
-
- if(msb.numBytes != 0)
- gxEditPostError(dp, gx_edit_internal_fatal_error);
-
- DisposePtr(msb.sb.buffer);
-
- /* now lets convert the gxStyle to a gxStyle index */
-
- gxStyle.textStyle = GXGetShapeStyle(emptyShape);
- gxStyle.textSize = FixedToInt(GXGetStyleTextSize(gxStyle.textStyle));
- gxStyle.textFont = GXGetStyleFont(gxStyle.textStyle);
-
- *styleIndex = FindDocStyle(dp, &gxStyle);
-
- if(*styleIndex == -1)
- *styleIndex = AddDocTextStyle(dp, gxStyle.textStyle);
-
- GXDisposeShape(emptyShape);
-
- }
-
- static void WriteStyle(DocPtr dp, Handle scrap, long * pos, short styleIndex)
- {
- MySpoolBlock msb;
- gxShape emptyShape;
- long startOfStyle;
- long endOfStyle;
- StylePtr sp;
- long styleSize = 0; /* need a dummy value, 'cause it gets rewritten later */
-
- startOfStyle = *pos; /* save the position so that we can write out the actual size of the gxStyle */
-
- WriteLong(scrap, pos, styleSize);
-
- /* save out the flatten gxStyle information */
-
- msb.sb.buffer = NewPtr(kBufferSize);
- msb.sb.bufferSize = kBufferSize;
- msb.sb.spoolProcedure = MySpoolProcedure;
-
- msb.numBytes = 0;
- msb.buf = scrap;
- msb.pos = pos;
- msb.start = *pos;
- msb.dp = dp;
-
- /* create an empty gxShape and set the gxStyle to the gxStyle we want to save */
-
- sp = GetDocStyle(dp, styleIndex);
-
- emptyShape = GXNewShape(gxEmptyType);
- GXSetShapeStyle(emptyShape, sp->textStyle);
-
- /* look into setting the flags so that a list of fonts that are used is generated */
-
- GXFlattenShape(emptyShape, (gxFlattenFlag) 0, (gxSpoolBlock *) &msb);
-
- /* dispose of the temporary gxShape */
-
- GXDisposeShape(emptyShape);
-
- /* free up the buffer */
-
- DisposePtr(msb.sb.buffer);
-
- /* now record the actual gxStyle size */
-
- endOfStyle = *pos;
-
- styleSize = endOfStyle - startOfStyle - sizeof(long);
-
-
- if(msb.numBytes != styleSize) /* double check the number of bytes written */
- gxEditPostError(dp, gx_edit_internal_fatal_error);
-
- *pos = startOfStyle;
- WriteLong(scrap, pos, styleSize);
- *pos = endOfStyle;
-
-
- }
-
- static long MySpoolProcedure(gxSpoolCommand command, gxSpoolBlock * sb)
- {
- long count;
- MySpoolBlock * msb;
-
- msb = (MySpoolBlock *) sb;
-
- switch(command) {
-
- case gxOpenReadSpool:
- case gxOpenWriteSpool:
-
- *msb->pos = msb->start;
-
- break;
-
- case gxReadSpool:
-
- count = sb->count;
-
- if(count > msb->numBytes) {
-
- count = msb->numBytes;
- sb->bufferSize = msb->numBytes;
-
- }
-
- ReadData(msb->buf, msb->pos, sb->buffer, count);
-
- msb->numBytes -= count;
-
- break;
-
- case gxWriteSpool:
-
- count = sb->count;
-
- WriteData(msb->buf, msb->pos, sb->buffer, count);
-
- msb->numBytes += count;
-
- break;
-
- case gxCloseSpool:
- break;
- }
-
- return(noErr);
-
- }
-
-
- static void ScrapToText(DocPtr dp, Handle * textPtr, long * textSizePtr, Handle * stylePtr, long * styleSizePtr)
- {
- long pos;
- long numRuns;
- NewRunPtr rp;
- short i;
- Handle text, gxStyle;
- ScrpSTElement * sp;
- StScrpRec * spHdr;
- long styleSize;
-
- pos = 0;
- text = NewHandle(0);
-
- numRuns = dp->scrap.numRuns;
-
- styleSize = sizeof(short) + (sizeof(ScrpSTElement) * numRuns);
- gxStyle = NewHandle(styleSize);
-
- HLock((Handle) gxStyle);
- HLock((Handle) dp->scrap.runs);
-
- spHdr = (StScrpRec *) *gxStyle;
-
- spHdr->scrpNStyles = numRuns;
- sp = (ScrpSTElement *) &spHdr->scrpStyleTab;
-
- rp = * dp->scrap.runs;
- for(i=0; i<numRuns; i++, rp++) {
- SetStyle(dp, rp->styleIndex, sp++, pos);
- WriteData(text, &pos, *rp->text, rp->numText);
- }
-
- HUnlock((Handle) dp->scrap.runs);
- HUnlock((Handle) gxStyle);
-
- *textPtr = text;
- *textSizePtr = pos;
- *stylePtr = gxStyle;
- *styleSizePtr = styleSize;
- }
-
- static void TextToScrap(DocPtr dp, Handle text, Handle gxStyle)
- {
- NewRunPtr rp;
- short numText;
- short numStyles;
- StScrpRec * styleHdr;
- ScrpSTElement * sp;
- short styleIndex;
- short pos;
- short runLength;
-
- HLock((Handle) text);
-
- if(gxStyle != nil) {
-
- HLock((Handle) gxStyle);
-
- styleHdr = (StScrpRec *) *gxStyle;
-
- numStyles = styleHdr->scrpNStyles;
-
- sp = (ScrpSTElement *) &styleHdr->scrpStyleTab;
-
- } else {
-
- numStyles = 0;
- sp = nil;
-
- }
-
- gxEditEmptyScrap(dp);
-
- styleIndex = dp->emptyStyle; /* default gxStyle is the current empty gxStyle */
- numText = GetHandleSize(text);
-
- if(numStyles > 0)
- dp->scrap.numRuns = numStyles;
- else
- dp->scrap.numRuns = 1;
-
-
- SetHandleSize((Handle) dp->scrap.runs, sizeof(NewRunRec) * dp->scrap.numRuns);
- dp->scrap.numText = numText;
-
- HLock((Handle) dp->scrap.runs);
-
- rp = *dp->scrap.runs;
- pos = 0;
-
- while(pos < numText) {
-
- if(numStyles)
- runLength = sp->scrpStartChar - pos;
- else
- runLength = numText - pos;
-
- if(runLength) {
-
- NewNewRun(dp, rp, styleIndex);
-
- InsertNewRunText(dp, rp, 0, *text + pos, runLength);
-
- pos += runLength;
- }
-
- if(numStyles) {
-
- styleIndex = GetStyle(dp, sp);
-
- numStyles--;
- sp++;
- }
-
- }
-
- HUnlock((Handle) text);
- HUnlock((Handle) dp->scrap.runs);
-
- if(gxStyle != nil)
- HUnlock((Handle) gxStyle);
-
- }
-
- static short GetStyle(DocPtr dp, ScrpSTElement * sp)
- {
- short scrapSize, styleIndex;
- gxFont textFont;
- Str255 gxFontName;
-
- scrapSize = sp->scrpSize;
- if (scrapSize <= 0)
- scrapSize = GetDefFontSize();
-
- styleIndex = SetDocStyleTextSize(dp, 0, scrapSize);
-
- GetFontName(sp->scrpFont, gxFontName);
-
- textFont = (gxFont) -1;
-
- GXFindFonts(nil, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxNoLanguage,
- gxFontName[0], &gxFontName[1], 1, 1, &textFont);
-
- if(textFont != (gxFont) -1)
- styleIndex = SetDocStyleTextFont(dp, styleIndex, textFont);
-
- return(styleIndex);
- }
-
- static void SetStyle(DocPtr dp, short styleIndex, ScrpSTElement * sp, long start)
- {
- gxFont textFont;
- short textSize;
- short fontNum;
- short oldTextSize;
- short oldFontNum;
- FontInfo info;
- long textFace;
-
- textFont = GetDocStyleTextFont(dp, styleIndex);
- textSize = GetDocStyleTextSize(dp, styleIndex);
-
- if (textSize <= 0 || textSize >= 127)
- textSize = GetDefFontSize();
-
- fontNum = FontToQD(textFont, &textFace);
-
- /* gxFontName[0] = GXFindFontName(textFont, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxNoLanguage,*/
- /* &gxFontName[1], nil);*/
- /* */
- /* GetFNum(gxFontName, &fontNum);*/
-
- /* This assumes a grafPort is alive somewhere !!! */
-
- oldFontNum = qd.thePort->txFont;
- oldTextSize = qd.thePort->txSize;
- TextFont(fontNum);
- TextSize(textSize);
- GetFontInfo(&info);
- TextSize(oldTextSize);
- TextFont(oldFontNum);
-
- sp->scrpStartChar = start;
- sp->scrpHeight = info.ascent + info.descent;
- sp->scrpAscent = info.ascent;
- sp->scrpFont = fontNum;
- sp->scrpFace = textFace;
- sp->scrpSize = textSize;
- sp->scrpColor.red = 0;
- sp->scrpColor.green = 0;
- sp->scrpColor.blue = 0;
-
- }
-
-